package fr.ginvest.entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="investisseur_type",discriminatorType=DiscriminatorType.CHAR)
@Table(name = "investisseur", uniqueConstraints={ @UniqueConstraint (columnNames={"login"})})
public class Investisseur implements Serializable {

	private static final long serialVersionUID = 987398873850412239L;
	
	public enum Genre{FEMININ, MASCULIN, MIXTE}
	public enum Etat{ACTIF, INACTIF}
	public enum Type{ANGEL, FONDATEUR, GROUPE}
	public enum ConnectionReseau{OUI, NON}
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO) 
	private int id;

	@Basic(optional=false)
	private String nom;

	@Column(nullable=true)
	private String prenom = "";
	
	@Basic(optional=false)
	private String login;

	@Basic(optional=false)
	private String motDePasse;
	
	private double fondPropre;
	
	@Temporal(TemporalType.DATE)
	private java.util.Date dateCreation;
	
	@Enumerated(EnumType.STRING)
	@Column(length=7, nullable=false)
	private Etat etat;
	
	@Enumerated(EnumType.STRING)
	@Column(length=8, nullable=false)
	private Genre genre;
	
	@Column(length=20)
	private String telephone;
	
	@Enumerated(EnumType.STRING)
	@Column(length=9, nullable=false)
	private Type type;
	
	@Enumerated(EnumType.STRING)
	@Column(length=3, nullable=false)
	private ConnectionReseau connectionReseau = ConnectionReseau.NON;
	
	@OneToMany(cascade = CascadeType.ALL, mappedBy = "investisseur", fetch=FetchType.EAGER)
	private Collection<Participation> participations = new ArrayList<Participation>();
	
	@OneToMany(cascade = CascadeType.ALL, mappedBy = "investisseur", fetch=FetchType.EAGER)
	private Set<Commentaire> commentaires = new HashSet<Commentaire>();
	
	@OneToMany(cascade = CascadeType.ALL, mappedBy = "investisseur", fetch=FetchType.EAGER)
	private Set<Article> articles = new HashSet<Article>();
	
	@ManyToMany(fetch=FetchType.EAGER)
	@JoinTable(name="investisseur_investisseur_groupe",uniqueConstraints={ @UniqueConstraint (columnNames={"investisseur_id","groupe_id"})},
			inverseJoinColumns={@JoinColumn(name="groupe_id",referencedColumnName="id")},
			joinColumns={@JoinColumn(name="investisseur_id",referencedColumnName="id")})
	private Set<GroupeInvestisseur> groupes = new HashSet<GroupeInvestisseur>();
	
	public Investisseur() {}

	public Investisseur(String login, String nom, String prenom, String motDePasse, int fondPropre) {
		this.login = login;
		this.nom = nom;
		this.prenom = prenom;
		this.motDePasse = motDePasse;
		this.fondPropre = fondPropre;
		this.dateCreation = new java.util.Date();
	}

	public Investisseur(String login, String nom, String motDePasse, int fondPropre) {
		this.login = login;
		this.nom = nom;
		this.motDePasse = motDePasse;
		this.fondPropre = fondPropre;
		this.dateCreation = new java.util.Date();
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Investisseur other = (Investisseur) obj;
		if (id != other.id)
			return false;
		return true;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getMotDePasse() {
		return motDePasse;
	}

	public void setMotDePasse(String motDePasse) {
		this.motDePasse = motDePasse;
	}

	public double getFondPropre() {
		return fondPropre;
	}

	public void setFondPropre(double fondPropre) {
		this.fondPropre = fondPropre;
	}

	public Collection<Participation> getParticipations() {
		return participations;
	}

	public void setParticipations(Collection<Participation> participations) {
		this.participations = participations;
	}
	
	public void addParticipation(Participation p) {
		this.participations.add(p);
	}

	public void setLogin(String login) {
		this.login = login;
	}
	
	public String getLogin() {
		return login;
	}

	public java.util.Date getDateCreation() {
		return dateCreation;
	}
	
	public void setDateCreation(java.util.Date dateCreation) {
		this.dateCreation = dateCreation;
	}
	
	public String getNom() {
		return nom;
	}

	public void setNom(String nom) {
		this.nom = nom;
	}

	public String getPrenom() {
		return prenom;
	}

	public void setPrenom(String prenom) {
		this.prenom = prenom;
	}
	
	public Etat getEtat() {
		return etat;
	}

	public void setEtat(Etat etat) {
		this.etat = etat;
	}
	
	public Genre getGenre() {
		return genre;
	}

	public void setGenre(Genre genre) {
		this.genre = genre;
	}
	
	public String getTelephone() {
		return this.telephone;
	}

	public void setTelephone(String telephone) {
		this.telephone = telephone;
	}
	
	public Type getType() {
		return this.type;
	}

	public void setType(Type type) {
		this.type = type;
	}
	
	public void setGroupes(Set<GroupeInvestisseur> groupes) {
		this.groupes = groupes;
	}
	
	public void addGroupe(GroupeInvestisseur groupe) {
		this.groupes.add(groupe);
	}
	
	public Set<GroupeInvestisseur> getGroupes() {
		return groupes;
	}
	
	public boolean matchPassword(String pwd) {
        if (pwd == null || "".equals(pwd))
            return false;
        
        if (pwd.equals(motDePasse))
            return true;
        else
        	return false;
    }
	
	public Double getTotalParticipations() {
		Double montant = (double) 0;
        for(Participation p : this.getParticipations()){
        	montant = montant + p.getMontant();
        }
        return montant;
    }
	
	public void setArticles(Set<Article> articles) {
		this.articles = articles;
	}
	
	public Set<Article> getArticles() {
		return articles;
	}
	
	public void setConnectionReseau(ConnectionReseau connectionReseau) {
		this.connectionReseau = connectionReseau;
	}
	
	public ConnectionReseau getConnectionReseau() {
		return this.connectionReseau;
	}
	
	public Set<Commentaire> getCommentaires() {
		return commentaires;
	}

	public void setCommentaires(Set<Commentaire> commentaires) {
		this.commentaires = commentaires;
	}
	
	public void addCommentaire(Commentaire c) {
		this.commentaires.add(c);
	}
}
